home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / hardware / 386id / 386id2.asm < prev    next >
Assembly Source File  |  1994-02-23  |  17KB  |  712 lines

  1.      title     ID386PPI -- PPI Subroutines to 386ID
  2.      page     58,122
  3.      name     ID386PPI
  4.  
  5. COMMENT|        Module Specifications
  6.  
  7. Copyright:  (C) Copyright 1987-94 Qualitas, Inc.
  8.  
  9. Segmentation:  Group PGROUP:
  10.            Program segment CODE,  word-aligned,  public, class 'prog'
  11.            Data    segment DATA,  dword-aligned, public, class 'data'
  12.  
  13. Original code by:  Bob Smith, November, 1987.
  14.  
  15. |
  16.  
  17. .386
  18. .xlist
  19.      include MISC.INC
  20. .list
  21.  
  22.  
  23. PGROUP     group     CODE,DATA
  24.  
  25.  
  26. DATA     segment use16 dword public 'data' ; Start DATA segment
  27.      assume  ds:PGROUP
  28.  
  29.      extrn     LCL_FLAG:word
  30.      include ID3_LCL.INC
  31.  
  32.      extrn     XMSDRV_VEC:dword
  33.  
  34. @XMS_LCLENA equ  05h        ; Local Enable A20
  35. @XMS_LCLDIS equ  06h        ; Local Disable A20
  36.  
  37. ACTA20_STR struc
  38.  
  39. ACTA20_MC  dw     ?
  40. ACTA20_ISA dw     ?
  41. ACTA20_XMS dw     ?
  42.  
  43. ACTA20_STR ends
  44.  
  45.      public  ACTA20_ENA
  46. ACTA20_ENA ACTA20_STR <PGROUP:A20ENA_MC,PGROUP:A20ENA_ISA,PGROUP:A20ENA_XMS>
  47.  
  48.      public  ACTA20_DIS
  49. ACTA20_DIS ACTA20_STR <PGROUP:A20DIS_MC,PGROUP:A20DIS_ISA,PGROUP:A20DIS_XMS>
  50.  
  51. DATA     ends            ; End DATA segment
  52.  
  53.  
  54. CODE     segment use16 word public 'prog' ; Start CODE segment
  55.      assume  cs:PGROUP
  56.  
  57.      NPPROC  A20ENA_MC -- A20 Enable for MC Systems
  58.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  59. COMMENT|
  60.  
  61. A20 enable for Micro Channel Systems
  62.  
  63. On entry:
  64.  
  65. AL     =     @PS2_A port value
  66.  
  67. On exit:
  68.  
  69. AL     =     (updated to enable A20)
  70.  
  71. |
  72.  
  73.      or     al,mask $PS2_GATE ; Enable A20
  74.  
  75.      ret            ; Return to caller
  76.  
  77.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  78.  
  79. A20ENA_MC endp            ; End A20ENA_MC procedure
  80.      NPPROC  A20ENA_ISA -- A20 Enable for ISA
  81.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  82. COMMENT|
  83.  
  84. A20 enable for ISA
  85.  
  86. On entry:
  87.  
  88. AL     =     output port byte
  89.  
  90. On exit:
  91.  
  92. AL     =     (updated to enable A20)
  93.  
  94. |
  95.  
  96.      or     al,mask $S2O_OBFUL ; Ensure output buffer marked as full
  97.      or     al,mask $S2O_GATE ; Enable A20
  98.  
  99.      ret            ; Return to caller
  100.  
  101.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  102.  
  103. A20ENA_ISA endp         ; End A20ENA_ISA procedure
  104.      NPPROC  A20ENA_XMS -- A20 Enable for XMS Drivers
  105.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  106. COMMENT|
  107.  
  108. A20 enable for XMS drivers
  109.  
  110. On exit:
  111.  
  112. AH     =     XMS function code to enable A20
  113.  
  114. |
  115.  
  116.      mov     ah,@XMS_LCLENA ; Enable A20
  117.  
  118.      ret            ; Return to caller
  119.  
  120.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  121.  
  122. A20ENA_XMS endp         ; End A20ENA_XMS procedure
  123.      NPPROC  GATEA20 -- Enable Address Line A20
  124.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  125. COMMENT|
  126.  
  127. Enable address line A20.
  128. Different systems require different techniques.  Here we
  129. differentiate MC systems from non-MC systems only.
  130.  
  131. On exit:
  132.  
  133. CF     =     0 if all went well
  134.      =     1 if we couldn't enable A20
  135.  
  136. |
  137.  
  138.      push     bx        ; Save register
  139.  
  140.      lea     bx,ACTA20_ENA    ; CS:BX ==> enable A20 actions
  141.  
  142.      jmp     short ACTA20_COM ; Join common code
  143.  
  144.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  145.  
  146. GATEA20  endp            ; End GATEA20 procedure
  147.      NPPROC  A20DIS_MC -- A20 Disable for MC Systems
  148.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  149. COMMENT|
  150.  
  151. A20 disable for Micro Channel systems
  152.  
  153. On entry:
  154.  
  155. AL     =     @PS2_A port value
  156.  
  157. On exit:
  158.  
  159. AL     =     (updated to disable A20)
  160.  
  161. |
  162.  
  163.      and     al,not (mask $PS2_GATE) ; Disable A20
  164.  
  165.      ret            ; Return to caller
  166.  
  167.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  168.  
  169. A20DIS_MC endp            ; End A20DIS_MC procedure
  170.      NPPROC  A20DIS_ISA -- A20 Disable for ISA
  171.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  172. COMMENT|
  173.  
  174. A20 disable for ISA
  175.  
  176. On entry:
  177.  
  178. AL     =     output port byte
  179.  
  180. On exit:
  181.  
  182. AL     =     (updated to disable A20)
  183.  
  184. |
  185.  
  186.      or     al,mask $S2O_OBFUL ; Ensure output buffer marked as full
  187.      and     al,not (mask $S2O_GATE) ; Disable A20 gate
  188.  
  189.      ret            ; Return to caller
  190.  
  191.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  192.  
  193. A20DIS_ISA endp         ; End A20DIS_ISA procedure
  194.      NPPROC  A20DIS_XMS -- A20 Disable for XMS Drivers
  195.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  196. COMMENT|
  197.  
  198. A20 disable for XMS drivers
  199.  
  200. On exit:
  201.  
  202. AH     =     XMS function code to enable A20
  203.  
  204. |
  205.  
  206.      mov     ah,@XMS_LCLDIS ; Disable A20
  207.  
  208.      ret            ; Return to caller
  209.  
  210.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  211.  
  212. A20DIS_XMS endp         ; End A20DIS_XMS procedure
  213.      NPPROC  DEGATEA20 -- Disable Address Line A20
  214.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  215. COMMENT|
  216.  
  217. Disable address line A20.
  218. Different systems require different techniques.  Here we
  219. differentiate MC systems from non-MC systems only.
  220.  
  221. On exit:
  222.  
  223. CF     =     0 if all went well
  224.      =     1 if we couldn't disable A20
  225.  
  226. |
  227.  
  228.      push     bx        ; Save register
  229.  
  230.      lea     bx,ACTA20_DIS    ; CS:BX ==> disable A20 actions
  231.  
  232.      jmp     short ACTA20_COM ; Join common code
  233.  
  234.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  235.  
  236. DEGATEA20 endp            ; End DEGATEA20 procedure
  237.      NPPROC  ACTA20_COM -- A20 Enable/Disable Common Routine
  238.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  239. COMMENT|
  240.  
  241. A20 enable/disable common routine
  242. Different systems require different techniques.  Here we
  243. differentiate MC systems from non-MC systems only.
  244.  
  245. On entry:
  246.  
  247. BX     pushed onto stack
  248. CS:BX     ==>     enable/disable action structure
  249.  
  250. |
  251.  
  252.      push     ax        ; Save register
  253.  
  254.      clc            ; Assume all goes well
  255.      lahf            ; Load AH with flags
  256.  
  257.      pushf            ; Save flags
  258.      cli            ; Disallow interrupts
  259.  
  260.      cmp     XMSDRV_VEC,0    ; Is there an XMS driver?
  261.      jz     short ACTA20_COM_NOXMS ; Not this time
  262.  
  263.      call     PGROUP:[bx].ACTA20_XMS ; Call common XMS action
  264.      call     XMSDRV_VEC    ; Request XMS service
  265.  
  266.      jmp     short ACTA20_COM_EXIT ; Join common exit code
  267.  
  268. ACTA20_COM_NOXMS:
  269.  
  270.      test     LCL_FLAG,@LCL_MC ; Izit an MC-compatible machine?
  271.      jz     short ACTA20_COM_XMC ; Not this time
  272.  
  273.      in     al,@PS2_A    ; Get system control port A
  274.      call     PGROUP:[bx].ACTA20_MC ; Call common MC action
  275.      out     @PS2_A,al    ; Tell the system about it
  276.  
  277.      jmp     short ACTA20_COM_EXIT ; Join common exit code
  278.  
  279. ACTA20_COM_XMC:
  280.  
  281. ; Write the output port byte
  282.  
  283.      REGSAVE <ax>        ; Save for a moment
  284.  
  285. ; First, clear any pending scan code from the output buffer
  286. ; This might lose a keystroke
  287.  
  288.      call     WAITOBUF_CLR    ; Wait for the output buffer to clear
  289.  
  290.      mov     ah,@S2C_ROUT    ; Read output port byte command
  291.      call     PPI_S2C_K2S    ; Send AH to 8042, return with AL = response
  292.      jc     short ACTA20_COM_ERR0 ; Jump if error (note CF=1)
  293.  
  294.      call     PGROUP:[bx].ACTA20_ISA ; Call common ISA action
  295.      mov     ah,@S2C_WOUT    ; Write output port byte
  296.      call     PPI_S2C_S2K    ; Write command AH, data AL to 8042
  297.      jc     short ACTA20_COM_ERR0 ; Jump if error (note CF=1)
  298.  
  299.      call     PULSE8042    ; Pulse the 8042 to ensure A20 toggle done
  300.                 ; Return with CF significant
  301. ACTA20_COM_ERR0:
  302.      pushf            ; Save previous flags
  303.  
  304. ; Last, enable the keyboard
  305.  
  306.      mov     ah,@S2C_ENA    ; Enable the keyboard
  307.      call     PPI_S2C    ; Send command AH to 8042
  308.                 ; Ignore error return
  309.      popf            ; Restore previous flags
  310. ACTA20_COM_ERR1:
  311.      REGREST <ax>        ; Restore
  312. ACTA20_COM_ERR:
  313.      adc     ah,0        ; Set CF in AH image of flags as necessary
  314. ACTA20_COM_EXIT:
  315.      popf            ; Restore flags
  316.  
  317.      sahf            ; Store AH into flags
  318.  
  319.      pop     ax        ; Restore
  320.  
  321.      pop     bx        ; Restore
  322.  
  323.      ret            ; Return to caller
  324.  
  325.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  326.  
  327. ACTA20_COM endp         ; End ACTA20_COM procedure
  328.      NPPROC  PPI_S2C -- PPI System to Controller
  329.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  330. COMMENT|
  331.  
  332. PPI System to Controller.
  333. Send a command to the controller (8042).
  334.  
  335. Note that it's the caller's responsibility to ensure that
  336. the 8042 output buffer is clear.
  337.  
  338. 1.  Wait for the input buffer to clear to avoid overrun.
  339. 2.  Send the command in AH to the keyboard controller port 64h.
  340.     There is no acknowledgement of this command.
  341.  
  342. On entry:
  343.  
  344. AH     =     command
  345. IF     =     0
  346.  
  347. On exit:
  348.  
  349. CF     =     1 if keyboard controller not responding
  350.      =     0 otherwise
  351.  
  352. |
  353.  
  354.      call     WAITIBUF_CLR    ; Wait for input buffer to clear
  355.      jc     short @F    ; Error, controller not reading data (note CF=1)
  356.  
  357.      xchg     al,ah        ; Swap to put command in AL
  358.      out     @8042_ST,al    ; Send the command
  359.      xchg     al,ah        ; Restore
  360. @@:
  361.      ret            ; Return to caller
  362.  
  363.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  364.  
  365. PPI_S2C  endp            ; End PPI_S2C procedure
  366.      NPPROC  PPI_S2C_K2S -- PPI System to Controller, Keyboard to System
  367.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  368. COMMENT|
  369.  
  370. PPI System to Controller, Keyboard to System
  371. Send a command to the controller (8042), wait for a response.
  372.  
  373. Note that it's the caller's responsibility to ensure that
  374. the 8042 output buffer is clear.
  375.  
  376. 1.  Send the command to the 8042.
  377. 2.  Wait for the output buffer to fill.
  378. 3.  Read the response.
  379.  
  380. Note that resend does not occur with the controller (8042)
  381. (although it can with the keyboard (6805)).
  382.  
  383. On entry:
  384.  
  385. AH     =     S2C command
  386. IF     =     0
  387.  
  388. On exit:
  389.  
  390. CF     =     0 if all went OK
  391.      =     1 otherwise
  392.  
  393. AL     =     byte read (if CF=0)
  394.  
  395. |
  396.  
  397.      call     PPI_S2C    ; Send command AH to 8042
  398.      jc     short @F    ; Jump if something went wrong (note CF=1)
  399.  
  400.      call     PPI_K2S    ; Wait for a response, returned in AL
  401.                 ; Return with CF significant
  402. @@:
  403.      ret            ; Return to caller
  404.  
  405.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  406.  
  407. PPI_S2C_K2S endp        ; End PPI_S2C_K2S procedure
  408.      NPPROC  PPI_S2C_S2K -- PPI System to Controller, System to Keyboard
  409.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  410. COMMENT|
  411.  
  412. PPI System to Controller, System to Keyboard.
  413.  
  414. Note that it's the caller's responsibility to ensure that
  415. the 8042 output buffer is clear.
  416.  
  417. 1.  Send the command to the 8042.
  418. 2.  Send the data to the 8042.
  419.  
  420. On entry:
  421.  
  422. AH     =     S2C command
  423. AL     =     byte to send
  424. IF     =     0
  425.  
  426. On exit:
  427.  
  428. CF     =     0 if all went OK
  429.      =     1 otherwise
  430.  
  431. |
  432.  
  433.      call     PPI_S2C    ; Send command AH to 8042
  434.      jc     short PPI_S2C_S2K_EXIT ; Jump if something went wrong (note CF=1)
  435.  
  436.      out     @8255_A,al    ; Send data AL to 8042
  437. PPI_S2C_S2K_EXIT:
  438.      ret            ; Return to caller
  439.  
  440.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  441.  
  442. PPI_S2C_S2K endp        ; End PPI_S2C_S2K procedure
  443.      NPPROC  PPI_K2S -- PPI Keyboard to System
  444.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  445. COMMENT|
  446.  
  447. PPI Keyboard to System.
  448. Wait for a response from the keyboard or its controller.
  449.  
  450. On entry:
  451.  
  452. IF     =     0
  453.  
  454. On exit:
  455.  
  456. CF     =     1 if no response
  457.      =     0 otherwise
  458.  
  459. AL     =     response if CF=0
  460.  
  461. |
  462.  
  463.      call     WAITOBUF_SET    ; Wait for the output buffer to fill
  464.      jc     short @F    ; Jump if no timely response (note CF=1)
  465.  
  466.      in     al,@8255_A    ; Read in the code
  467. @@:
  468.      ret            ; Return to caller
  469.  
  470.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  471.  
  472. PPI_K2S  endp            ; End PPI_K2S procedure
  473.      NPPROC  PPI_S2K -- PPI System to Keyboard
  474.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  475. COMMENT|
  476.  
  477. PPI System to Keyboard.
  478. Send command to keyboard.
  479.  
  480. 1.  Wait for the input buffer to clear to avoid overrun.
  481. 2.  Send the command in AH to the keyboard port 60h.
  482.     There is no acknowledgement of this command.
  483.  
  484. On entry:
  485.  
  486. AH     =     command to send
  487. IF     =     0
  488.  
  489. On exit:
  490.  
  491. CF     =     1 if timeout
  492.      =     0 otherwise
  493.  
  494. AL     =     keyboard response if CF=0
  495.  
  496. |
  497.  
  498.      call     WAITIBUF_CLR    ; Wait for input buffer to clear
  499.      jc     short @F    ; Error, controller not reading data (note CF=1)
  500.  
  501.      xchg     al,ah        ; Swap to put command in AL
  502.      out     @8255_A,al    ; Issue the command
  503.      xchg     al,ah        ; Restore
  504. @@:
  505.      ret            ; Return to caller
  506.  
  507.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  508.  
  509. PPI_S2K  endp            ; End PPI_S2K procedure
  510.      NPPROC  PPI_S2K_K2S -- PPI System to Keyboard, Keyboard to System
  511.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  512. COMMENT|
  513.  
  514. PPI System to Keyboard, Keyboard to System.
  515. Send command to keyboard (6805), wait for its response.
  516.  
  517. Note that it's the caller's responsibility to ensure that
  518. the 6805 output buffer is clear.
  519.  
  520. 1.  Send the command to the 6805.
  521. 2.  Wait for the output buffer to fill.
  522. 3.  Read the response.
  523. 4.  Check for resend.
  524.  
  525. On entry:
  526.  
  527. AH     =     command to send
  528. IF     =     0
  529.  
  530. On exit:
  531.  
  532. CF     =     1 if timeout
  533.      =     0 otherwise
  534.  
  535. AL     =     keyboard response if CF=0
  536.  
  537. |
  538.  
  539.      push     cx        ; Save for a moment
  540.  
  541.      mov     cx,6        ; # retries of resend (arbitrary value)
  542. PPI_S2K_K2S_AGAIN:
  543.      call     PPI_S2K    ; Send command AH to 6805
  544.      jc     short PPI_S2K_K2S_EXIT ; Jump if something went wrong (note CF=1)
  545.  
  546.      call     PPI_K2S    ; Wait for a response, returned in AL
  547.      jc     short PPI_S2K_K2S_EXIT ; Jump if something went wrong (note CF=1)
  548.  
  549.      cmp     al,@K2S_RESEND ; Izit a resend?
  550.      clc            ; In case not
  551.      jne     short PPI_S2K_K2S_EXIT ; Jump if not (note CF=0)
  552.  
  553.      loop     PPI_S2K_K2S_AGAIN ; Jump if more retries
  554.  
  555.      stc            ; Indicate something went wrong
  556. PPI_S2K_K2S_EXIT:
  557.      pop     cx        ; Restore
  558.  
  559.      ret            ; Return to caller
  560.  
  561.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  562.  
  563. PPI_S2K_K2S endp        ; End PPI_S2K_K2S procedure
  564.      NPPROC  WAITIBUF_CLR -- Wait For The Input Buffer To Clear
  565.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  566. COMMENT|
  567.  
  568. Wait for the one-byte input buffer to clear.
  569.  
  570. On entry:
  571.  
  572. IF     =     0
  573.  
  574. On exit:
  575.  
  576. CF     =     0 if buffer empty
  577.      =     1 otherwise
  578.  
  579. |
  580.  
  581.  
  582.      REGSAVE <ax,cx>    ; Save registers
  583.  
  584.      mov     ah,6        ; Outer loop counter (arbitrary value)
  585.      xor     cx,cx        ; Inner loop counter (arbitrary value)
  586. WAITIBUF_CLR1:
  587.      in     al,@8042_ST    ; Get status from keyboard
  588.  
  589.      and     al,mask $INPFULL ; Check Input Buffer Full flag
  590.      loopnz  WAITIBUF_CLR1    ; Last char not read as yet
  591.      jz     short WAITIBUF_CLR_EXIT ; Jump if buffer clear (note CF=0)
  592.  
  593.      dec     ah        ; One fewer time
  594.      jnz     short WAITIBUF_CLR1 ; Go around again
  595.  
  596.      stc            ; Indicate something went wrong
  597. WAITIBUF_CLR_EXIT:
  598.      REGREST <cx,ax>    ; Restore
  599.  
  600.      ret            ; Return to caller
  601.  
  602.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  603.  
  604. WAITIBUF_CLR endp        ; End WAITIBUF_CLR procedure
  605.      NPPROC  WAITOBUF_CLR -- Wait For The Output Buffer To Clear
  606.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  607. COMMENT|
  608.  
  609. Wait for the one-byte output buffer to clear.
  610.  
  611. On entry:
  612.  
  613. IF     =     0
  614.  
  615. |
  616.  
  617.      push     ax        ; Save for a moment
  618. WAITOBUF_CLR1:
  619.      in     al,@8042_ST    ; Get status from keyboard
  620.  
  621.      and     al,mask $OUTFULL ; Check Output Buffer Full flag
  622.      jz     short WAITOBUF_CLR_EXIT ; Jump if buffer clear before
  623.  
  624.      jmp     short $+2    ; I/O delay
  625.      jmp     short $+2    ; I/O delay
  626.      jmp     short $+2    ; I/O delay
  627.  
  628.      in     al,@8255_A    ; Purge the character
  629.      jmp     short $+2    ; I/O delay
  630.      jmp     short $+2    ; I/O delay
  631. ;;;;;;;; jmp     short $+2    ; I/O delay
  632.  
  633.      jmp     short WAITOBUF_CLR1 ; Go around again
  634.  
  635. WAITOBUF_CLR_EXIT:
  636.      pop     ax        ; Restore
  637.  
  638.      ret            ; Return to caller
  639.  
  640.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  641.  
  642. WAITOBUF_CLR endp        ; End WAITOBUF_CLR procedure
  643.      NPPROC  WAITOBUF_SET -- Wait for Output Buffer Full
  644.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  645. COMMENT|
  646.  
  647. Wait for the output buffer to fill.
  648.  
  649. On entry:
  650.  
  651. IF     =     0
  652.  
  653. On exit:
  654.  
  655. CF     =     1 if no response
  656.      =     0 otherwise
  657.  
  658. |
  659.  
  660.      REGSAVE <ax,cx>    ; Save registers
  661.  
  662. ; Wait for a response
  663.  
  664.      mov     ah,6        ; Outer loop counter (arbitrary value)
  665.      xor     cx,cx        ; Inner loop counter (arbitrary value)
  666. WAITOBUF_SET1:
  667.      in     al,@8042_ST    ; Get status from keyboard
  668.  
  669.      and     al,mask $OUTFULL ; Check Output Buffer Full flag
  670.      loopz     WAITOBUF_SET1    ; Jump if no response as yet
  671.      jnz     short WAITOBUF_SET_EXIT ; Join common exit code (note CF=0)
  672.  
  673.      dec     ah        ; One fewer time
  674.      jnz     short WAITOBUF_SET1 ; Jump if more tries available
  675.  
  676.      stc            ; Indicate something went wrong
  677. WAITOBUF_SET_EXIT:
  678.      REGREST <cx,ax>    ; Restore
  679.  
  680.      ret            ; Return to caller
  681.  
  682.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  683.  
  684. WAITOBUF_SET endp        ; End WAITOBUF_SET procedure
  685.      NPPROC  PULSE8042 -- Pulse 8042
  686.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  687. COMMENT|
  688.  
  689. Pulse the 8042 to ensure the last command has been accepted.
  690. Typically (if needed at all), this is necssary after toggling A20
  691. on an ISA bus machine.
  692.  
  693. |
  694.  
  695. ; Pulse the controller to ensure the last 8042 command has been processed
  696.  
  697.      push     ax        ; Save for a moment
  698.      mov     ah,@S2C_RESET    ; Ensure in a stable state
  699.      call     PPI_S2C    ; Send command AH to 8042
  700.      pop     ax        ; Restore
  701.                 ; Return with CF significant
  702. PULSE8042_EXIT:
  703.      ret            ; Return to caller
  704.  
  705.      assume  ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
  706.  
  707. PULSE8042 endp            ; End PULSE8042 procedure
  708.  
  709. CODE     ends            ; End CODE segment
  710.  
  711.      MEND            ; End 386ID2 module
  712.